#ifndef __SERVER_HPP
#define __SERVER_HPP

#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<string>
#include<map>
#include<stdlib.h>
#include<functional>
#include<unistd.h>
#include"Protocol.hpp"
#include<sys/wait.h>
#define NUM 5
#endif

class Server{
    private:
      int _port;
      int _lsock;
      std::map<char,std::function< void(struct request&,struct response&)>> opMap=
      {
        {'+',[&](struct request& requ,struct response& resp ){ resp.result = requ.x+requ.y; }},
        {'-',[&](struct request& requ,struct response& resp ){ resp.result = requ.x-requ.y; }},
        {'*',[&](struct request& requ,struct response& resp ){ resp.result = requ.x*requ.y; }},
        {'/',[&](struct request& requ,struct response& resp ){
            if(requ.y==0) resp.code = 1;               
            else resp.result = requ.x/requ.y; 
            }
        }
      };//声明时给缺省
    public:
      Server(int port)
      :_port(port),
       _lsock(-1)
  {

  }
      void ServerInit()
      {
          _lsock = socket(AF_INET, SOCK_STREAM, 0);
          
          struct sockaddr_in local;
          local.sin_family = AF_INET;
          local.sin_port = htons(_port);
          local.sin_addr.s_addr = INADDR_ANY; 

          if( bind(_lsock ,(struct sockaddr*)&local,sizeof(local)  ) < 0 )
          {
              std::cerr << "bind error "<< std::endl;
              exit(1);
          }

          if( listen(_lsock,NUM) < 0 )
          {
              std::cerr << "listen error "<<std::endl;
              exit(2);
          }
      }
      void service(int sock)
      {
           /*短连接*/  
           struct request requ;
        
           recv( sock , &requ, sizeof(requ), 0 );
            
           struct response resp; 
           resp.code = 0; //默认为0
           std::cout<<"get a task:"<<std::endl; 
           std::cout<<requ.x << " "<<requ.op << " "<<requ.y <<std::endl;

           std::cout<<resp.code<<" "<<resp.result<<std::endl;
           if(!opMap.count((requ.op)))  resp.code = 3;//输入的符号不存在
           else {
               auto res = opMap[requ.op];
               res(requ,resp);
           }
           //auto func= [&](struct request& requ,struct response& resp ){ resp.result = requ.x+requ.y; };
          // func(requ,resp);
          // std::cout<<resp.code<<" "<<resp.result<<std::endl;
           send( sock, &resp , sizeof(resp), 0 );
           close(sock);
      }
      void start()
      {
          struct sockaddr_in end_point;
          while(true)
          {
            
              socklen_t len = sizeof(end_point);//细节

              int sock = accept( _lsock, (struct sockaddr*)&end_point,&len );

              if( sock < 0 )
              {
                  std::cerr <<" accept false " <<std::endl;
                  continue;
              }
              std::cout <<" get a link ..."<<std::endl;
              if( fork() == 0 )
              {
                  if( fork() > 0 )
                  {
                     exit(0);
                  }
                  //孙子进程处理逻辑
                  close(_lsock);
                  service(sock);
                  exit(0);
              } 
              waitpid( -1 ,nullptr,0);
              close(sock);
          }
      }
      ~Server()
      {
         close(_lsock);
      }
};
